package com.unitd.configclient.listener.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.unitd.configclient.ConfigcenterContext;
import com.unitd.configclient.listener.IConfigChangeListener;
import com.unitd.frame.comm.utils.BeanUtils;
import com.unitd.frame.comm.utils.http.HttpResponseEntity;
import com.unitd.frame.comm.utils.http.HttpUtils;
import com.unitd.frame.spring.prop.ResourceUtils;
import com.unitd.frame.comm.utils.StringUtils;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @desc 配置中心服务端改动监听类
 * 当配置中心服务端与客户端采用http直连方式时,客户端直接与服务端进行交互,可以直接从配置中心服务端获取与当前应用相关的属性配置信息
 * @filename HttpConfigChangeListener.java
 * @copyright www.unitd.com
 * @author Hudan
 * @version 1.0
 * @date 2018/1/14
 */
public class HttpConfigChangeListener implements IConfigChangeListener {

	private ScheduledExecutorService hbScheduledExecutor;

	/**
	 * @desc 获取当前服务与配置中心服务端进行心跳服务监听的方式(zookeeper/redis/http, 默认http)
	 * @return 同步方式名称
	 */
	@Override
	public String typeName() {
		return "http";
	}

	/**
	 * @desc 注册当前服务与配置中心服务端(也可以时zookeeper/redis)的心跳服务,获取服务端配置信息
	 * @param context 配置中心上线文信息对象
	 */
	@Override
	public void register(final ConfigcenterContext context) {
		hbScheduledExecutor = new ScheduledThreadPoolExecutor(1);

		// 轮询向注册中心发起异步状态查询请求
		final String[] syncStatusUrls = new String[context.getApiBaseUrls().length];
		for (int i = 0; i < context.getApiBaseUrls().length; i++) {
			syncStatusUrls[i] = context.getApiBaseUrls()[i] + "/api/sync_status";
		}

		final Map<String, String> params = new HashMap<>(3);
		params.put("nodeId", context.getNodeId());
		params.put("appName", context.getApp());
		params.put("env", context.getEnv());
		hbScheduledExecutor.scheduleAtFixedRate(new Runnable() {
			@Override
			public void run() {
				// 由于初始化的时候还拿不到spring.cloud.client.ipAddress，故在同步过程上送
				if (context.isSpringboot()) {
					String serverip = ResourceUtils.getProperty("spring.cloud.client.ipAddress");
					if (StringUtils.isNotBlank(serverip)) {
						params.put("serverip", serverip);
					}
				}

				boolean updated = false;
				for (String url : syncStatusUrls) {
					HttpResponseEntity response = HttpUtils.doPost(url, JSON.toJSONString(params), HttpUtils.DEFAULT_CHARSET);
					if (updated) return;
					// 刷新服务端更新的配置
					if (updated = response.isSuccessed()) {
						JSONObject jsonObject = JSON.parseObject(response.getBody());
						if(!BeanUtils.isNull(jsonObject)) {
							Map map = JSON.parseObject(jsonObject.getString("data"), Map.class);
							context.updateConfig(map);
						}
					}
				}
			}
		}, 30, context.getSyncIntervalSeconds(), TimeUnit.SECONDS);
	}

	/**
	 * @desc 断开当前服务与配置中心服务端的链接
	 */
	@Override
	public void unRegister() {
		hbScheduledExecutor.shutdown();
	}
}